package cn.agrael.ref;

import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;

/**
 * 用做 ReferenceMap 的清除引用的引用队列。
 * @author <a href="http://www.agrael.cn">李翔</a>
 *
 */
class FinalizableReferenceQueue extends ReferenceQueue<Object> {

	private FinalizableReferenceQueue() {}
	
	private static class FinalizeReferenceQueueInstance{
		private static final FinalizableReferenceQueue INSTANCE = new FinalizableReferenceQueue();
		static {
			INSTANCE.start();
		}
	}

	/**
	 * 得到 FinalizableReferenceQueue 的单例。
	 * @return FinalizableReferenceQueue 的单例。
	 */
	public static FinalizableReferenceQueue getInstance(){
		return FinalizeReferenceQueueInstance.INSTANCE;
	}
	
	/**
	 * 执行引用的清除工作。
	 * @param reference 要执行清除工作的引用。
	 */
	void cleanUp(Reference<?> reference) {
		try {
			((FinalizableReference<?>) reference).finalizeReferent();
		} catch (Throwable t) {
			t.printStackTrace();
		}
	}
	
	/**
	 * 开始垃圾回收引用监视。
	 */
	void start() {
		Thread thread = new Thread("清除垃圾回收引用队列") {
			
			@Override
			public void run() {
				while (true) {
					try {
						cleanUp(remove());
					} catch (InterruptedException e) {
					}
				}
			}
		};
		thread.setDaemon(true);
		thread.start();
		System.out.println("垃圾回收引用监视器开始工作。");
	}
}
